var TagSupport = {
	// options = {id,formSubmit,formQuery,url,type,dataType,async,timeout,cache,
	//	onSuccess,onError,autoSend,silent,onBeforeSend,onComplete,contentType}
	'ajax':function(options) {
		ObjectUtil.cleanup(options, ['onBeforeSend','onComplete','onSuccess','onError','onServiceError']);
		if (StringUtil.isNotEmpty(options.data)) {
			var s = "var x = " + options.data;
			eval(s);
			options.data = x;
			options.odata = x;
		}
		var opt = {
			'formSubmit':(StringUtil.isEmpty(options.formQuery)  ? false : true),
			'silent':false,
			'autoSend':false,
			'contentType':'application/json',
			'type':'get',
			'dataType':'json'
		};
		opt = $.extend(opt, FunctionEmbedUtil); // 具备执行函数队列的能力，embedFunction,executeEmbedFunctions
		opt = $.extend(opt, options);
		var ajaxSetting = {
			'send':function() {
				if (this.formSubmit && StringUtil.isNotEmpty(this.formQuery)) {
					var frmData = $(this.formQuery).serializeObject();
					this.odata = {};
					$.extend(this.odata, this.data); // 将扩展form 的数据前的data备份至this.odata，以便恢复
					frmData = $.extend(this.data, frmData);
					
					$(this.formQuery).ajaxFormUnbind();
					var mFormSetting = {
						'data':frmData
					};
					var formSetting = $.extend(this, mFormSetting);
					$(this.formQuery).ajaxForm(formSetting);
				}
				$.mAjax(this);
				this.urlRestore();
				this.data = this.odata; // 不保留form带来的数据
			},
			'urlRestore':function() {
				if (this.oUrl) {
					this.url = this.oUrl;
					this.oUrl = null;
				}
			},
			'success':function(data,status,xhr) {
				if(!data){
					Logger.debug("ajax => " + this.id + "没有返回任何数据！");
					return ;
				}
				if(data.success==false || data.success == 'false'){ // data 中可能没有 isSuccess 属性
					var message = data.message || "系统错误";
					MsgBox.error(message, null, function() {
						opt.executeEmbedFunctions(function(item){
							item && item(data, status, xhr);
						}, 'onServiceError', this);
						opt.onServiceError && onServiceError(data,status,xhr);
					});
					Logger.error("ajax send error , message: " + message);
					return ;
				}
				// 是否根据后台返回来进行提示，当存在onSucccess，prompt属性失效
				if (opt.prompt && !this.onSuccess) {
					MsgBox.info(data.message);
				}
				try{
					opt.executeEmbedFunctions(function(item){
						item && item(data, status, xhr);
					}, 'onSuccess', this);
					this.onSuccess && this.onSuccess(data,status,xhr);
				}catch(e){
					//Logger.error("执行用户的success回调方法失败 e.message = " + e.stack);
					window['console'] && console.error(e.stack);
				}
			},
			'error':function(xhr,textStatus,errorThrown) {
				MsgBox.error("访问服务器失败");
				try{
					this.executeEmbedFunctions(function(item){
						item && item(xhr,textStatus,errorThrown);
					}, 'onError', this);
					this.onError && this.onError(xhr,textStatus,errorThrown);
				}catch(e){
					// Logger.error(e.message);
					window['console'] && console.error(e.stack);
				}
			},
			'beforeSend':function(xhr){
				if(!this.silent)
					MsgBox.startLoading();
				try{
					this.executeEmbedFunctions(function(item){
						item && item(xhr);
					}, 'onBeforeSend', this);
					this.onBeforeSend && this.onBeforeSend(xhr);
				}catch(e){
					// Logger.error(e.message);
					window['console'] && console.error(e.stack);
				}
			},
			'complete':function(xhr,textStatus){
				if(!this.silent)
					MsgBox.stopLoading();
				this.executeEmbedFunctions(function(item){
					item && item(xhr, textStatus);
				}, 'onComplete', this);
				this.onComplete && this.onComplete(xhr,textStatus);
			},
			'addParam':function(key,value) {
				if(this.data==undefined)
					this.data={};
				this.data[key] = value;
			},
			'setData':function(data) {
				this.data = data;
			},
			'tempUrl':function(func) {
				this.oUrl = this.url;
				var tUrl = func(this.url);
				this.url = tUrl;
				return this;
			}
		};
		ajaxSetting = $.extend(ajaxSetting, opt);
		window[ajaxSetting.id] = ajaxSetting;
		ajaxSetting.autoSend && ajaxSetting.send();
	},
	/*{id,ajax,onCurrentNodeSelected,onMutiNodesSelected,defaultSelectIndex,showRemoveBtn,
		canEdit,checkable,selectedMulti,showLine,dblClickExpand,
		convertToTemplate,nodeNameKey,nodeUrlKey,nodeCheckedKey,nodeChildrenKey,nodeTitleKey,
		nodeIdKey,parentIdKey,rootPidValue,maxLayer,className,dataStructure,silent,onAsyncError,
		onAsyncSuccess,onlyShowFolder,showIcon,drag,onDrag,rename,onDrop,style,selectRootNode
	}*/
	'tree':function(options) {
		ObjectUtil.cleanup(options, ['onAsyncError','onAsyncSuccess','onCurrentNodeSelected','onChecked','onMutiNodesSelected','convertToTemplate',
		    'ajax','onDrag','onDrop']);
		var opt = {
			'showRemoveBtn':false,
			'canEdit':false,
			'checkable':false,
			'showLine':true,
			'selectedMulti':false,
			'dblClickExpand':true,
			'defaultSelectIndex':0,
			'nodeNameKey':'text',
			'nodeUrlKey':'url',
			'nodeTitleKey':'title',
			'nodeChildrenKey':'children',
			'nodeCheckedKey':'checked',
			'nodeIdKey':'id',
			'parentIdKey':'pid',
			'rootPidValue':null,
			'maxLayer': 9999,
			'dataStructure':'array',
			'expandAll':false,
			'triggerRecorder':new TriggerRecorder(), // 影响树变化的触发点记录器
			'idStrategy':'uuid', // 生成ID的策略，可选值，uuid/timestamp/none，默认uuid
			'onlyShowFolder':false,  'showIcon':true,
			'drag':'none',           'isMove':false,
			'isCopy':false,          'rename':false,
			'style':'none',          'selectRootNode':false,
			'addDiyDom':null
		};
		
		opt = $.extend(opt, options);
		// 当可拖动时，canEdit设置为true
		if (opt.drag != 'none') {
			opt.canEdit = true;
			if (opt.drag == 'move') {
				opt.isCopy = !(opt.isMove = true);
			} else {
				opt.isCopy = !(opt.isMove = false);
			}
		}
		
		// 主题
		if (opt.style == 'outlook') {
			opt.addDiyDom = function(treeId, treeNode) {
				var spaceWidth = 5;
	            var switchObj = $("#" + treeNode.tId + "_switch"),
	            icoObj = $("#" + treeNode.tId + "_ico");
	            switchObj.remove();
	            icoObj.before(switchObj);

	            if (treeNode.level > 1) {
	                var spaceStr = "<span style='display: inline-block;width:" + (spaceWidth * treeNode.level)+ "px'></span>";
	                switchObj.before(spaceStr);
	            }
			};
		}
		
		if (opt.rename) {
			opt.canEdit = true;
		}
		opt.$tree = $('#' + opt.id);
		
		opt.stopLoading = function() {
			opt.$tree.closest('.m-loader-wrapper').stopLoading();
		};
		opt.startLoading = function() {
			opt.$tree.closest('.m-loader-wrapper').startLoading();
		};
		var oSucc = opt.ajax.onSuccess;
		opt.ajax.onSuccess = function(odata, status, xhr) {
			oSucc && oSucc(odata, status, xhr);
			opt.stopLoading();
	        // 数据处理
	        var data = null;
	        if (!(odata instanceof Array)) {
	            data = odata.info;
	        } else {
	            data = odata;
	        }
	        if (opt.dataStructure == 'array') {
	            data = $.toTree({
	                "data":data,
	                "rootPidValue":opt.rootPidValue,
	                "children":opt.nodeChildrenKey,
	                "contentDefine":{
	                    "id":opt.nodeIdKey,   "pid":opt.parentIdKey
	                }
	            });
	        }
            var setting = {
        		view : {
                    dblClickExpand: opt.dblClickExpand,           showLine: opt.showLine,    selectedMulti: opt.selectedMulti,
                    showIcon:opt.showIcon,                        addDiyDom:opt.addDiyDom
                },
                data:{
                    keep: {parent : true, leaf : false },
                    simpleData : {
                        enable : true,    idKey : opt.nodeIdKey,   pIdKey: opt.parentIdKey,    rootPId : ""
                    },
                    key:{
                        name: opt.nodeNameKey, 			url: opt.nodeUrlKey,    title: opt.nodeTitleKey,   checked: opt.nodeCheckedKey,
                        children: opt.nodeChildrenKey,  id:opt.nodeIdKey,       pid:opt.parentIdKey
                    }
                },
                edit: {
                    enable: opt.canEdit,  showRemoveBtn: opt.showRemoveBtn,   isCopy:opt.isCopy,  isMove:opt.isMove, showRenameBtn:opt.rename
                },
                callback : {
                    onClick : function(event, treeId, treeNode, clickFlag) { // 点击显示节点到内容
                        var zTree = $.fn.zTree.getZTreeObj(opt.id);
                        var nodes = zTree.getSelectedNodes();
                        opt.onMutiNodesSelected && opt.onMutiNodesSelected(nodes);
                        
                        // 限制仅单击时触发
                        $.excludeDbClick(opt.id, 250, function() {
                    		opt.onCurrentNodeSelected && opt.onCurrentNodeSelected(nodes[0]);
                        });
                        
                        return nodes;
                    },
                    onAsyncError: function(event, treeId, treeNode, XMLHttpRequest, textStatus, errorThrown) {
                        opt.onAsyncError && opt.onAsyncError(event, treeId, treeNode, XMLHttpRequest, textStatus, errorThrown);
                    },
                    onAsyncSuccess :function(event, treeId, treeNode, msg) {
                        opt.onAsyncSuccess && opt.onAsyncSuccess(event, treeId, treeNode, msg);
                    },
                    onCheck:function(event, treeId, treeNode) {
                    	opt.triggerRecorder.doChange();
                    	opt.onChecked && opt.onChecked(event, treeId, treeNode);
                    },
                    onDrag:function(event, treeId, treeNodes) {
                    	opt.onDrag && opt.onDrag(event, treeId, treeNodes);
                    },
                    beforeDrop:function(treeId, treeNodes, targetNode, moveType) {
                    	var nodeDepth = $.getTreeDepth(treeNodes[0], opt.nodeChildrenKey, opt.nodeIdKey);
                    	var targetNodeDepth = targetNode.level + 1;
                    	if (nodeDepth + targetNodeDepth > opt.maxLayer) {
                    		$.messager.info('移动失败，可以允许的最大层级为' + opt.maxLayer + ",移动后的最大层级为" + (nodeDepth + targetNodeDepth));
                    		return false;
                    	} 
                    	return true;
                    },
                    onDrop:function(event, treeId, treeNodes, targetNode, moveType) {
                    	opt.onDrop && opt.onDrop(event, treeId, treeNodes, targetNode, moveType);
                    }
                },
                check: {
                	chkStyle : "checkbox",
                	enable : opt.checkable, 
                	chkboxType : { "y" :"ps", "N" : "ps"}
                }
            };
            // data[opt.defaultSelectIndex].open = 'true';// 展开首页
            
            $.fn.zTree.init($("#"+opt.id), setting, data);
            if (opt.expandAll) {
            	$.fn.zTree.getZTreeObj(opt.id).expandAll(true);
            }
            
            if (opt.onlyShowFolder) {
            	// 控制叶子节点也显示为文件夹
            	$("#" + opt.id).addClass("ztree-only-folder");
        	}
            
            if (opt.style == 'outlook') {
            	var treeObj = $("#" + opt.id);
            	treeObj.addClass("showIcon");
//            	treeObj.hover(function () {
//            		if (!treeObj.hasClass("showIcon")) {
//            			treeObj.addClass("showIcon");
//            		}
//            	}, function() {
//            		treeObj.removeClass("showIcon");
//            	});
            }
            
            var tree = window[opt.id];
            if (opt.selectRootNode) {
            	tree.selectFirstRootNode();
            }
		};
		var onError = opt.ajax.onError;
		opt.ajax.onError = function(xhr,textStatus,errorThrown) {
			opt.stopLoading();
			onError && onError(xhr,textStatus,errorThrown);
		};
		var onComplete = opt.ajax.onComplete;
		opt.ajax.onComplete = function(xhr,textStatus) {
			opt.stopLoading();
			onComplete && onComplete(xhr,textStatus);
		};
		var onBeforeSend = opt.ajax.onBeforeSend;
		opt.ajax.onBeforeSend = function(xhr) {
			opt.silent || opt.startLoading();
			onBeforeSend && onBeforeSend(xhr);
		};
		var tree = {
			'recorder':new Recorder(),
			// 获取操作记录器
			'getRecorder':function() {
				return this.recorder;
			},
			// 根据关键词搜索
			'search':function(key) {
				if ($.trim(key)) {
					opt.$tree.find("[treenode]").hide();
					opt.$tree.find("span.node_name:contains(" + key  + ")").parents("[treenode]").show();
				} else {
					opt.$tree.find("[treenode]").show();
				}
			},
			// 选中第一个节点
			'selectFirstRootNode': function(){
				var treeObj = this.getZTreeObj();
				var nodes = treeObj.getNodes();
				if (nodes.length > 0) {
					treeObj.selectNode(nodes[0]);
					opt.onCurrentNodeSelected && opt.onCurrentNodeSelected(nodes[0]);
				}
			},
			// 选中节点，node:节点对象，zTree 内部的数据对象
			// 			zTree 内部的数据对象，true:表示追加选中，会出现多点同时被选中的情况
			//   		                                      ，false表示单独选中，原先被选中的节点会被取消选中状态
			'selectNode': function(node,addFlag) {
				var treeObj = this.getZTreeObj();
				treeObj.selectNode(node,addFlag);
				// 触发选中事件
				this.onCurrentNodeSelected && this.onCurrentNodeSelected(node);
			},
			// 将ztree节点转为你所需要的节点
			'converNodeToTemplate':function(node,index){
				return node;
			},
			// 将ZTree 的nodes实例转为你所需要的nodes
			'getZTreeNodesToTemplates': function(){
				var treeObj = $.fn.zTree.getZTreeObj(this.id);
				var nodes = treeObj.transformToArray(treeObj.getNodes());
				var arr = new Array();
				
				var _this = this;
				$.each(nodes,function(index,item){
					var nodeIndex = treeObj.getNodeIndex(item); // 当前节点在同级节点中的第几个节点
					var template = _this.converNodeToTemplate(item,nodeIndex);
					arr.push(template);
				});
				return arr;
			},
			// 更新一个节点, 
			'updateNode': function(node,refresh){
				var zTree = this.getZTreeObj();
				refresh = refresh ==undefined ? true: refresh;
				zTree.updateNode(node, refresh);// 执行内容更改
				this.recorder.getUpdateRecords().put(node);
			},
			// 
			'getJsonArrayOfNodes': function(){
				var treeObj = $.fn.zTree.getZTreeObj(opt.id);
				var nodes = treeObj.transformToArray(treeObj.getNodes());
				var jsonArr = JSON.stringify(nodes);
				return jsonArr;
			},
			// 获取ZTree对象
			'getZTreeObj': function(){
				return $.fn.zTree.getZTreeObj(opt.id);
			},
			// 展开所有节点
			'expandAll': function(){
				var treeObj = $.fn.zTree.getZTreeObj(opt.id);
				treeObj.expandAll(true);
			},
			// 设置选中或取消所有节点，false:取消所有勾选/true:勾选所有 默认
			'checkAllNodes': function(flag){
				flag = (flag == "false" || flag == false)?false:true;
				var treeObj = $.fn.zTree.getZTreeObj(opt.id);
				treeObj.checkAllNodes(flag);
			},
			// 根据id数组来选中节点
			'checkNodesWithIdArray': function(nodeIdArr,checked, beforeCancelAll, checkTypeFlag,callbackFlag){
				checked == (checked=="false"||checked==false) ? false : true;
				checkTypeFlag == (checkTypeFlag=="true" || checkTypeFlag==true) ? true : false;
				callbackFlag == (callbackFlag=="true" || callbackFlag==true) ? true : false;
				var treeObj = $.fn.zTree.getZTreeObj(opt.id);
				beforeCancelAll == false || treeObj.checkAllNodes(false);
				if(nodeIdArr != undefined && nodeIdArr != null){
					for(var i=0;i<nodeIdArr.length;i++){
						var node = treeObj.getNodeByParam(opt.nodeIdKey, nodeIdArr[i], null);
						treeObj.checkNode(node,checked,checkTypeFlag,callbackFlag);
					}
				}
			},
			// 获取选中的节点
			'getCheckNodes': function(flag){
				var treeObj = $.fn.zTree.getZTreeObj(opt.id);
				flag == (flag=="false"||flag==false)?false:true;
				return treeObj.getCheckedNodes(flag);
			},
			'getCheckedNodeIds':function(flag) {
				var nodes = this.getCheckNodes(flag);
				return $.toPropertyValueArray(nodes, opt.nodeIdKey);
			},
			// 根据id 查找节点
			'_findNodeById': function(nodes,idKey,childrenKey,id) {
			    for(var i=0; i < nodes.length; i++){
			        var item = nodes[i];
			        var tItem = this._findNodeById(item[childrenKey],idKey,childrenKey,id);
			        if (tItem != null) {
			            return tItem;
			        }
			        if (item[idKey] == id) {
			            return item;
			        }
			    }
			    return null;
			},
			'selectNodeById': function(id) {
				this.selectNode(this.findNodeById(id));
			},
			'findNodeById': function(id) {
				/*this.keys.nodeId*/
				var treeObj = this.getZTreeObj();
				var nodes = treeObj.getNodes();
				return this._findNodeById(nodes, this.keys.id, this.keys.children, id);
			},
			'getNodes': function(){
				var treeObj = this.getZTreeObj();
				var nodes = treeObj.getNodes();
				return nodes;
			},
			'getSelectedNodes': function(){
				var treeObj = $.fn.zTree.getZTreeObj(opt.id);
				var nodes = treeObj.getSelectedNodes();
				return nodes;
			},
			'getCurrentNode': function() {
				var nodes = this.getSelectedNodes();
				return nodes[0];
			},
			'cancelSelectedNode': function(node){
				node && this.getZTreeObj().cancelSelectedNode(node);
			},
			'cancelAllSelectedNodes': function(){
				this.getZTreeObj().cancelSelectedNode();
			},
			'removeNode': function(node) {
				if(node && node.id) {
					this.recorder.getDeleteRecords().put(node);
					this.getZTreeObj().removeNode(node);
					return true;
				}
				return false;
			},
			'addNode': function(node){
				// 组装节点信息
				var childNode = {};
				childNode['id'] = childNode[opt.nodeIdKey] = $.generateId(this.idStrategy);
				childNode[opt.nodeNameKey] = '新节点';
				
				// 向ztree中增加了新的节点后，返回当前节点及其子节点
				var newNodes = null; 
				var treeObj = this.getZTreeObj();
				if(node==null) { // 传入null，那么新增根节点
					newNodes = treeObj.addNodes(null, childNode);
				}else{
					var parentId = node[opt.nodeIdKey];
					if(!parentId) { // 选中节点没有id
						Logger.error("你所选中的节点id值为 null");
						return {};
					}
					childNode[opt.parentIdKey] = parentId;
					var parentZNode = node;
					if (parentZNode.level >= (opt.maxLayer-1) && opt.maxLayer != -1) {
						$.messager.info('添加新节点失败，你最多可以添加到第' + opt.maxLayer + '级');
						return {};
					}
					newNodes = treeObj.addNodes(parentZNode, childNode, true); // 得到新增加的节点
				}
				// 选中新增加的节点
				treeObj.selectNode(newNodes[0]); 
				this.recorder.getNewRecords().put(newNodes[0]);
				Logger.info("你正在新增ztree节点，新增的节点："+JSON.stringify(newNodes));
				return newNodes[0];
			},
			'refresh': function(flag){
				if (flag) {
					this.getRecorder().clearAll();
					opt.ajax.send();
				} else {
					this.getZTreeObj().refresh();
				}
			},
			// 展开/折叠所有节点
			'doExpandAll':function(flag) {
				this.getZTreeObj().expandAll(flag);
			},
			'getTriggerRecorder':function() {
				return this.triggerRecorder;
			}
		};
		
		tree = $.extend(tree, opt);
		window[opt.id] = tree;
		tree.ajax.send();
	},
	'operBar':function(options) {
		ObjectUtil.cleanup(options, ["onAdd","onDelete","onRefresh","onSave",'onSub']);
		var opt = {
			'style':'icon',
			'relations':{
				'icon':'ICON_SETTINGS'
			},
			'ICON_SETTINGS':{
				'items':{
					'delete':      { 'icon':'fa fa-trash fa-fw',   'text':'删除', 'funcName':'onDelete' },
					'sub':         { 'icon':'fa fa-minus fa-fw',   'text':'删除', 'funcName':'onSub'  },
					'add':         { 'icon':'fa fa-plus fa-fw' ,   'text':'添加', 'funcName':'onAdd'  },
					'refresh':     { 'icon':'fa fa-refresh fa-fw', 'text':'刷新', 'funcName':'onRefresh'  },
					'save':        { 'icon':'fa fa-save fa-fw',    'text':'保存', 'funcName':'onSave'  },
				},
				'getItemNode':function(mOpt, item) {
					var mItem = this.items[item];
					var $p = $("<a href='javascript:void(0);'><i></i></a>");
					$p.attr('title',mItem.text);
					$p.find('i').addClass(mItem['icon']);
					$p.off('click').on('click', function(e) {
						e.stopPropagation();
						e.preventDefault();
						mOpt[mItem.funcName] && mOpt[mItem.funcName](e); 
					});
					return $p;
				}
			}
		};
		$.extend(opt, options);
		var settings = opt[opt.relations[opt.style]];
		var items = opt.items.split(",");
		var $operBar = $("*[data-oper-bar='" + opt.id + "']");
		$operBar.attr('data-' + opt.style, "true");
		for (var i in items) {
			var item = items[i];
			var $node = settings.getItemNode(opt, item);
			$operBar.append($node);
		}
	},
	'datatable':function(options) {
		ObjectUtil.cleanup(options, ["ajax","afterReady","afterSort","onChecksChanged",
		                         "onRenderItem","onDoubleClick","onItemClick", "dataset"]);
		var opt = {
			'showLineNumber':true,
			'multiple':false
		};
		$.extend(opt, options);
		window[opt.id] = $("[data-datatable='" + opt.datatableId + "']#" + opt.id).datatable(opt);
	},
	'pagination':function(options) {
		ObjectUtil.cleanup(options, ["datatable"]);
		var opt = {
			'showPageChoice':true
		};
		$.extend(opt, options);
		var $pagination = $("#" + opt.id + "[data-pagination='" + opt.paginationId + "']");
		var mPagination = window[opt.id] = $pagination.pagination({
			'id': opt.id,
			'ajax': opt.datatable.getAjax(),
			'$pagination':$pagination,
			'rows':opt.pageSize,
			'datatable':opt.datatable,
			'pageChoice':opt.pageChoice,
			'showPageChoice':opt.showPageChoice,
			'pageSize':opt.pageSize
		});
		opt.datatable.setPagination(mPagination);
		mPagination.refresh();
	},
	/**
	 * 
	 * @参数 {dropValues}
	 */
	'dropValues':function(options) {
		// onSuccess, onChange
		ObjectUtil.cleanup(options, ["onValueChanged","dropValues"]);
		var opt = {
			'showSelectName':'请选择',
			'showSelectAll':false,
			'async':false,
			'contentDefine':{
				'text':'codeInfoName',
				'value':'codeInfoValue'
			}
		};
		$.extend(opt, options);
		
		if (opt.dropValues && !ArrayUtil.isArray(opt.dropValues)) {
			var arr = [];
			$.each(opt.dropValues, function(key, value) {
				var item = {};
				item[opt.contentDefine.text] = value;
				item[opt.contentDefine.value] = key;
				arr.push(item);
			});
			opt.dropValues = arr;
		}
		opt.data = opt.dropValues;
		var $select = $._buildSelect(opt);
		$("#" + opt.id + "[data-tag='dropList']").replaceWith($select);
	}
};





















